package com.demo.server.service;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.demo.server.constant.CommonConstant;
import com.demo.server.entity.User;
import com.demo.server.entity.UserRole;
import com.demo.server.entity.dto.UserDto;
import com.demo.server.entity.req.LoginReq;
import com.demo.server.entity.req.UserEditSelfReq;
import com.demo.server.entity.req.UserReq;
import com.demo.server.entity.req.UserSearchReq;
import com.demo.server.entity.resp.LoginResp;
import com.demo.server.mapper.RoleMapper;
import com.demo.server.mapper.UserMapper;
import com.demo.server.mapper.UserRoleMapper;
import com.demo.server.util.AccessTokenUtil;
import com.demo.server.util.MD5Util;
import com.demo.server.util.MyCacheUtil;
import com.demo.server.util.Result;
import com.demo.server.util.ResultData;
import com.demo.server.util.ResultPage;
import com.demo.server.util.UUIDUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.captcha.generator.MathGenerator;

@Service
public class UserService {
	
	@Autowired
	UserMapper userMapper;
	
	@Autowired
	RoleMapper roleMapper;
	
	@Autowired
	UserRoleMapper userRoleMapper;
	
	/**
	 * @title 登录
	 * @param req
	 * @return ResultData<LoginResp>
	 */
	public ResultData<LoginResp> login(LoginReq req) {
		// TODO Auto-generated method stub
		String captchaKey = req.getCaptchaKey();
		String captchaCode = req.getCaptchaCode();
		String verifyCode = MyCacheUtil.captchaCache.get(captchaKey);
		MathGenerator mg = new MathGenerator();
		if(StringUtils.isEmpty(verifyCode)) {
			return ResultData.failNull("验证码超失效");
		}else {
			MyCacheUtil.captchaCache.remove(captchaKey);//删除验证码
		}
		if(!mg.verify(verifyCode, captchaCode)) {
			return ResultData.failNull("验证码错误");
		}
		User loginUser = userMapper.selectByUsername(req.getUsername());
		if(loginUser == null || !MD5Util.encode32(req.getPassword()).equals(loginUser.getPassword())) {
			return ResultData.fail(null,"用户名或密码错误");
		}
		List<String> roleIds = roleMapper.selectIdByUserId(loginUser.getId());
		loginUser.setRoleIds(roleIds);
		StpUtil.login(loginUser.getId());
		StpUtil.getSession().set("user", loginUser);
		String token = StpUtil.getTokenValue();
		//跟新登录时间
		User user = new User();
		user.setId(loginUser.getId());
		user.setLasttime(new Date());
		userMapper.updateByPrimaryKeySelective(user);
		
		//返回登录结果
		LoginResp resp = new LoginResp();
		BeanUtils.copyProperties(loginUser, resp);
		resp.setRoleIds(roleIds);
		resp.setToken(token);		
		return ResultData.success(resp,"登录成功");
	}
	
	/**
	 * @title 退出登录
	 * @param req
	 * @return Result
	 */
	public Result logout() {
		String token = AccessTokenUtil.getAccessToken();
		if(StringUtils.isNoneEmpty(token)) {
			StpUtil.logout();
			//redisTemplate.delete(token);
		}
		return Result.success();
	}
	
	/**
	 * @title 查询用户
	 * @param req
	 * @return
	 */
	public ResultPage<User> search(UserSearchReq req){
		Page<Object> page = PageHelper.startPage(req.getPage(), req.getSize());
		UserDto dto = new UserDto();
		BeanUtils.copyProperties(req, dto);
		List<User> users = userMapper.select(dto);
		ResultPage<User> result = ResultPage.success(users,page.getTotal());
		return result;
	}
	
	public ResultData<User> detail(String id) {
		// TODO Auto-generated method stub
		User resp = new User();
		User user = userMapper.selectByPrimaryKey(id);
		BeanUtils.copyProperties(user, resp);
		resp.setRoleIds(userRoleMapper.selectRoleIdByUserId(id));
		return ResultData.success(resp);
	}
	
	@Transactional
	public Result add(UserReq req) {
		User user = new User();
    	BeanUtils.copyProperties(req, user);
        User existUser = userMapper.selectByUsername(user.getUsername());
        if(existUser==null){
        	user.setId(UUIDUtil.get32UUID());
            user.setPassword(MD5Util.encode32(CommonConstant.INI_PWD));
            user.setCreatetime(new Date());
            user.setLasttime(new Date());
            userMapper.insertSelective(user);
            if(req.getRoleIds() != null) {
    			userRoleMapper.deleteByUserId(user.getId());
             	UserRole ur = new UserRole();
             	ur.setUserId(user.getId());
             	for(String roleId : req.getRoleIds()) {
             		ur.setRoleId(roleId);
             		userRoleMapper.insert(ur);
             	}
             }
            return Result.success();
        }else {
        	return Result.fail("用户已存在");
        }		
	}
	
	@Transactional(rollbackFor = Exception.class)
	public Result edit(UserReq req) {
		User user = new User();
		BeanUtils.copyProperties(req, user);
		userMapper.updateByPrimaryKeySelective(user);
		 if(req.getRoleIds() != null) {
			userRoleMapper.deleteByUserId(user.getId());
         	UserRole ur = new UserRole();
         	ur.setUserId(user.getId());
         	for(String roleId : req.getRoleIds()) {
         		ur.setRoleId(roleId);
         		userRoleMapper.insert(ur);
         	}
         }
		return Result.success();
	}
	
	/**
	 * @title 自身修改
	 * @param req
	 * @return
	 */
	public Result editSelf(UserEditSelfReq req) {
		String userId = AccessTokenUtil.getUserId();
		User user = new User();
		BeanUtils.copyProperties(req, user);
		user.setId(userId);
		String password = user.getPassword();
		if(StringUtils.isEmpty(password)) {
			user.setPassword(null);
		}else {
			user.setPassword(MD5Util.encode32(password));
		}
		userMapper.updateByPrimaryKeySelective(user);
		return Result.success();
	}
	
	@Transactional
	public Result delete(String id) {
		// TODO Auto-generated method stub
		userMapper.deleteByPrimaryKey(id);
		userRoleMapper.deleteByUserId(id);
		return Result.success();
	}

}
